package com.tl.khadmin.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.tl.khadmin.bean.CostAdjust;
import com.tl.khadmin.bean.Order;
import com.tl.khadmin.bean.OrderProduct;
import com.tl.khadmin.bean.OrderRefund;
import com.tl.khadmin.bean.SettlementBill;
import com.tl.khadmin.bean.Supplier;
import com.tl.khadmin.enums.OrderStateEnum;
import com.tl.khadmin.mapper.CostAdjustMapper;
import com.tl.khadmin.mapper.OrderMapper;
import com.tl.khadmin.mapper.OrderProductMapper;
import com.tl.khadmin.mapper.OrderRefundMapper;
import com.tl.khadmin.mapper.SettlementBillMapper;
import com.tl.khadmin.mapper.SupplierMapper;
import com.tl.khadmin.service.GenerateOrderBillService;
import com.tl.khadmin.util.Constant;
import com.tl.khadmin.util.DateUtil;

@Service
public class GenerateOrderBillServiceImpl implements GenerateOrderBillService{
	
	private static Logger log=Logger.getLogger(GenerateOrderBillServiceImpl.class);
	@Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderProductMapper orderProductMapper;
    @Resource
    private OrderRefundMapper orderRefundMapper;
    @Resource
    private SettlementBillMapper settlementBillMapper; 
    @Resource
    private SupplierMapper supplierMapper;
    @Resource
    private CostAdjustMapper costAdjustMapper;
    
  /*  结算周期，1当日结算，2周结、3十日结、4月结*/

    /**
     * 每月一号生成上月账单
     * 生成月末十日账单，即21日到月末订单账号
     */
	@Override
	public void monthOrderBill() {
		
		//生成月账单
		Date date = new Date();
		Map<String, Object> param = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		param.put("paymentCycle", 4);
		param.put("status", OrderStateEnum.已签收.code());
		//签收时间范围
		param.put("startSignTime", DateUtil.getLastMonthStartTime(date));
		param.put("endSignTime", DateUtil.getLastMonthEndTime(date)); 
		List<Order> orderList = orderMapper.listOrder(param);
		
		//检索周期内退款订单信息，按退款时间查询
		Map<String, Object> queryOrderRefundParam = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		//param.put("paymentCycle", 2); 
		//实际退款时间范围
		queryOrderRefundParam.put("startRefundTime", DateUtil.getLastMonthStartTime(date));
		queryOrderRefundParam.put("endRefundTime", DateUtil.getLastMonthEndTime(date)); 
		List<OrderRefund> orderRefundList = orderRefundMapper.listOrderRefund(queryOrderRefundParam);
		
		//3、检索费用调整数据列表，按生成时间查询
		Map<String, Object> queryCostAdjustParam = new HashMap<String, Object>();  
		queryCostAdjustParam.put("startTime", DateUtil.getLastMonthStartTime(date));
		queryCostAdjustParam.put("endTime", DateUtil.getLastMonthEndTime(date)); 
		queryCostAdjustParam.put("isSettlement", 0); 
		List<CostAdjust> costAdjustList = costAdjustMapper.listCostAdjust(queryCostAdjustParam);
		
		log.info("生成一个月账单定时器，一个月内所有订单数量：" + orderList.size());
		Map<String, Object> queryParam = new HashMap<String, Object>();
		queryParam.put("paymentCycle", 4); 
		//月结供应商
		List<Supplier> supplierList = supplierMapper.listSupplier(queryParam);
		log.info("生成一个月账单定时器，供应商数量：" + supplierList.size());
		this.generateOrderBill(orderList, supplierList, orderRefundList, costAdjustList);
		
		
		
		//生成上月21日到月末的周结算订单账单
		Map<String, Object> params = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		params.put("paymentCycle", 2);
		params.put("status", OrderStateEnum.已签收.code());
		//签收时间范围
		params.put("startSignTime", DateUtil.getLastMonth21StartTime(date));
		params.put("endSignTime", DateUtil.getLastMonthEndTime(date)); 
		List<Order> oList = orderMapper.listOrder(params);
		log.info("生成一个月账单定时器，一个月内所有订单数量：" + orderList.size());
		
		//检索周期内退款订单信息，按退款时间查询
		Map<String, Object> queryOrderRefundParamTen = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		//param.put("paymentCycle", 2); 
		//实际退款时间范围
		queryOrderRefundParamTen.put("startRefundTime", DateUtil.getLastMonthStartTime(date));
		queryOrderRefundParamTen.put("endRefundTime", DateUtil.getLastMonthEndTime(date)); 
		List<OrderRefund> orderRefundTenDayList = orderRefundMapper.listOrderRefund(queryOrderRefundParamTen);
		
		//3、检索费用调整数据列表，按生成时间查询
		Map<String, Object> queryCostAdjustParam2 = new HashMap<String, Object>();  
		queryCostAdjustParam2.put("startTime", DateUtil.getLastMonthStartTime(date));
		queryCostAdjustParam2.put("endTime", DateUtil.getLastMonthEndTime(date)); 
		queryCostAdjustParam2.put("isSettlement", 0); 
		List<CostAdjust> costAdjustList2 = costAdjustMapper.listCostAdjust(queryCostAdjustParam2);
				
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("paymentCycle", 3);
		//周结供应商
		List<Supplier> supplierLists = supplierMapper.listSupplier(queryParams);
		log.info("生成一个月账单定时器，供应商数量：" + supplierList.size());
		this.generateOrderBill(oList, supplierLists, orderRefundTenDayList, costAdjustList2); 
	}
	
	
    /**
     * 生成每周账单，针对周结供应商的订单
     */
	@Override
	public void weekOrderBill() { 
		
		Date date = new Date();
		
		Map<String, Object> param = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		param.put("paymentCycle", 2);
		param.put("status", OrderStateEnum.已签收.code());
		//签收时间范围
		param.put("startSignTime", DateUtil.getLastWeekMondayTime(date));
		param.put("endSignTime", DateUtil.getLastWeekSundayTime(date)); 
		List<Order> orderList = orderMapper.listOrder(param);
		log.info("生成一周账单定时器，一周内所有订单数量：" + orderList.size());
		
		//检索周期内退款订单信息，按退款时间查询
		Map<String, Object> queryOrderRefundParam = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		//param.put("paymentCycle", 2); 
		//实际退款时间范围
		queryOrderRefundParam.put("startRefundTime", DateUtil.getLastWeekMondayTime(date));
		queryOrderRefundParam.put("endRefundTime", DateUtil.getLastWeekSundayTime(date)); 
		List<OrderRefund> orderRefundDayList = orderRefundMapper.listOrderRefund(queryOrderRefundParam);
		
		//3、检索费用调整数据列表，按生成时间查询
		Map<String, Object> queryCostAdjustParam = new HashMap<String, Object>();  
		queryCostAdjustParam.put("startTime", DateUtil.getLastWeekMondayTime(date));
		queryCostAdjustParam.put("endTime", DateUtil.getLastWeekSundayTime(date)); 
		queryCostAdjustParam.put("isSettlement", 0); 
		List<CostAdjust> costAdjustList = costAdjustMapper.listCostAdjust(queryCostAdjustParam);
		
		Map<String, Object> queryParam = new HashMap<String, Object>();
		queryParam.put("paymentCycle", 2);
		//周结供应商
		List<Supplier> supplierList = supplierMapper.listSupplier(queryParam);
		log.info("生成一周账单定时器，供应商数量：" + supplierList.size());  
		
		this.generateOrderBill(orderList, supplierList, orderRefundDayList, costAdjustList);
		
	}

	/**
	 * 生成每十日账单，针对十日结供应商的订单
	 */
	@Override
	public void tenDaysOrderBill() {
		Date date = new Date();
		
		//1、检索订单列表
		Map<String, Object> param = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		param.put("paymentCycle", 3);
		param.put("status", OrderStateEnum.已签收.code());
		//签收时间范围
		param.put("startSignTime", DateUtil.getTenDayBeforeStartTime(date));
		param.put("endSignTime", DateUtil.getLastDayEndTime(date)); 
		List<Order> orderList = orderMapper.listOrder(param);
		log.info("生成十天内账单定时器，十天内所有订单数量：" + orderList.size());
		
		//2、检索周期内退款订单信息，按退款时间查询
		Map<String, Object> queryOrderRefundParam = new HashMap<String, Object>();
		//结算周期，1当日结算，2周结、3十日结、4月结
		//param.put("paymentCycle", 2); 
		//实际退款时间范围
		queryOrderRefundParam.put("startRefundTime", DateUtil.getTenDayBeforeStartTime(date));
		queryOrderRefundParam.put("endRefundTime", DateUtil.getLastDayEndTime(date)); 
		List<OrderRefund> orderRefundList = orderRefundMapper.listOrderRefund(queryOrderRefundParam);
		
		//3、检索费用调整数据列表，按生成时间查询
		Map<String, Object> queryCostAdjustParam = new HashMap<String, Object>();  
		queryCostAdjustParam.put("startTime", DateUtil.getTenDayBeforeStartTime(date));
		queryCostAdjustParam.put("endTime", DateUtil.getLastDayEndTime(date)); 
		queryCostAdjustParam.put("isSettlement", 0); 
		List<CostAdjust> costAdjustList = costAdjustMapper.listCostAdjust(queryCostAdjustParam);
		
		//4、检索供应商列表
		Map<String, Object> queryParam = new HashMap<String, Object>();
		queryParam.put("paymentCycle", 3);
		//周结供应商
		List<Supplier> supplierList = supplierMapper.listSupplier(queryParam);
		log.info("生成十天内账单定时器，供应商数量：" + supplierList.size());
		
		
		this.generateOrderBill(orderList, supplierList, orderRefundList, costAdjustList);
	}
	
	/**
	 * 生成供应商订单账单
	 * @param orderList 订单列表
	 * @param supplierList 供应商列表
	 * @param orderRefundList 退款列表
	 * @param costAdjustList 费用调整列表
	 */
	private void generateOrderBill(List<Order> orderList, List<Supplier> supplierList, 
			List<OrderRefund> orderRefundList, List<CostAdjust> costAdjustList ) {
		for(Supplier supplier : supplierList) {
			boolean hasOrder = false;
			BigDecimal freight = new BigDecimal(0); 	//运费
			BigDecimal billAmount = new BigDecimal(0);	//供货价（不含税）
			BigDecimal orderAmount = new BigDecimal(0);	//订单总金额（付款价格）
			BigDecimal refundAmount = new BigDecimal(0);	//售后金额/退款金额 
			BigDecimal costAdjustAmount = new BigDecimal(0);	//调整金额 
			for(Order orde : orderList) {	
				if(orde.getSupplierId().longValue() == supplier.getId().longValue()) {		//按供应商生成该周期内的账单
					freight = freight.add(new BigDecimal(orde.getFreight()));
					orderAmount = orderAmount.add(new BigDecimal(orde.getOrderAmount()));
					
					List<OrderProduct> orderProduct = orderProductMapper.queryByOrderId(orde.getId());	// 取得该订单下所有商品
					for(OrderProduct oProduct : orderProduct) {
						billAmount = billAmount.add(
								new BigDecimal(oProduct.getUnitPrice()).
								multiply(new BigDecimal(oProduct.getSpecificationNumber())));	//计算该订单所有商品的供货总价
					}
					
					//处理退款信息 
					for(OrderRefund orderRefund : orderRefundList) {
						refundAmount = refundAmount.add(new BigDecimal(orderRefund.getAmount()));	//计算订单退款总额
					}
					
					//处理调整费用信息
					for(CostAdjust costAdjust : costAdjustList) {
						costAdjustAmount = costAdjustAmount.add(new BigDecimal(costAdjust.getAmount()));	//计算调整金额总额，注意带正负数
					}
					
					//过滤空额订单
					hasOrder = true;
				}
			} 
			if(hasOrder) {
				
				SettlementBill settlementBill = new SettlementBill();
				settlementBill.setSupplierId(supplier.getId());
				settlementBill.setSettlementType(supplier.getPaymentCycle());
				settlementBill.setCreateTime(new Date());
				settlementBill.setBillAmount(billAmount.doubleValue());
				settlementBill.setFreight(freight.doubleValue());
				settlementBill.setRefundAmount(refundAmount.doubleValue());
				settlementBill.setAdjustAmount(costAdjustAmount.doubleValue());
				settlementBill.setOrderAmount(orderAmount.doubleValue());
				BigDecimal taxBig = orderAmount.multiply(new BigDecimal(Constant.TAX_RATE));	//税额
				settlementBill.setTaxAmount(taxBig.doubleValue());		//税金（订单付款价格*税率（税率表）
				settlementBill.setSettlementAmount(billAmount.add(freight).subtract(refundAmount).add(taxBig).doubleValue());	//账单最后结算金额，供货价+运费-退款金额+税额
				int row = settlementBillMapper.insertSelective(settlementBill);
				log.info("生成账单定时器，插入账单主表返回值：" + row);
				
				if(row == 1) {
					
					//插入结算账单子订单记录
					for(Order orde : orderList) {
						if(orde.getSupplierId().longValue() == supplier.getId().longValue()) {
							int ret = settlementBillMapper.insertSettlementBillOrder(settlementBill.getId(), orde.getId());
							log.info("生成账单定时器，插入账单子表返回值：" + ret);
						}
					}
					
					//设置订单退款记录的账单信息，结算账单id、是否已生成结算账单
					if(orderRefundList != null && orderRefundList.size() > 0) {
						for(OrderRefund orderRefund : orderRefundList) {
							int r = orderRefundMapper.updateSettlement(1, settlementBill.getId(), orderRefund.getId());
							log.info("生成账单定时器，更新退款订单记录："+orderRefund.getId()+"，行数" + r);
						}
					} 
					
					//更新调整费用记录信息，结算账单id、是否已生成结算账单
					if(costAdjustList != null && costAdjustList.size() > 0) {
						for(CostAdjust costAdjust : costAdjustList) {
							int r = costAdjustMapper.updateSettlement(1, settlementBill.getId(), costAdjust.getId());
							log.info("生成账单定时器，更新费用调整记录："+costAdjust.getId()+"，行数" + r);
						}
					}
					
				}
			} 
		}
	} 
	
	
}
